<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
      <el-form-item label="像素点" prop="pixelNo">
        <el-input
          v-model="keyword"
          placeholder="请输入像素点"
          clearable
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="search">搜索</el-button>
      </el-form-item>
    </el-form>
    <div class="canvas-box">
      <canvas ref="canvas" id="canvas" class="canvas"></canvas>
    </div>
    <div class="mark-box"> {{ this.timeValue }} / {{this.maxTimeValue}}</div>
    <div class="timeline-box">
      <el-slider v-model="timeValue" :max="maxTimeValue" :min="minTimeValue" @change="changeTimeValue"></el-slider>
    </div>
    <div class="controls">
      <el-button :disabled="isAnimating" @click="startAnimation">播放</el-button>
      <el-button :disabled="!isAnimating" @click="pauseAnimation">暂停</el-button>
<!--      <el-select v-model="playbackSpeed" size="medium" @change="onPlaybackSpeedChange" style="margin-left: 20px">-->
<!--        <el-option v-for="speed in playbackSpeedOptions" :key="speed.value" :label="speed.label" :value="speed.value"></el-option>-->
<!--      </el-select>-->
    </div>
  </div>
</template>

<script>
    import { drawTrack, drawTrackSleeper, drawTrackCrossing} from './rail'
    import {querySleeperlist,querySleeperDataBySleeperNo,querySleeperMiniMaxiPixelNoData} from "@/api/system/sleeper";

    export default {
        name: 'CanvasTrack',
        data() {
            return {
                // 画布
                canvas: null,
                // 画布 高度
                canvasHeight: 660,
                // 画布 宽度
                canvasWidth: null,
                // 画布内容
                canvasContext: null,
                // 轨枕id集合
                sleeperIdSet: null,
                // 轨枕集合
                sleeperSet: null,
                keyword: 0,
                // 轨枕分页查询参数
                queryParams: {
                    lineNo: 'J8801',
                    pixelNo: 0,
                    moveSign: 'ADD',
                    moveNum: 25
                },
               querySleeperParams:{
                 lineNo: 'J8801',
                 sleeperNo: null
               },
                // 最小时间
                minTimeValue: 0,
                // 最大时间
                maxTimeValue: 10000,
                // 最小像素
                minPixelNo: null,
                // 最大像素
                maxPixelNo: null,
                //当前最大像素
                currentMaxPixelNo: null,
                //上一个时间
                preTimeValue: 0,
                // 当前时间
                timeValue: 0,
                // 动画
                isAnimating: false,
                // 动画标识
                animationId: null,
                // 播放速度
                playbackSpeed: 1, // 默认播放速度为1倍速
                // 播放速度列表
                playbackSpeedOptions: [ // 倍速选项数组
                    {label: '0.25x', value: 0.25},
                    {label: '0.5x', value: 0.5},
                    {label: '1x', value: 1},
                    {label: '1.5x', value: 1.5},
                    {label: '2x', value: 2}
                ]
            }
        },
        methods: {
            initCanvas() {
                this.canvasWidth = this.$refs.canvas.parentElement.clientWidth; // 获取父容器宽度
                this.animationId = null
                this.canvas = new fabric.Canvas('canvas', {
                    width: this.canvasWidth,
                    height: this.canvasHeight,
                    selection: false
                })
            },
            clearAll() {
                this.canvas.clear().renderAll()
            },
            renderSleeper(){
                this.clearAll()
                drawTrack(this.canvas, 0, 150, this.maxPixelNo, 150, 15)
                drawTrack(this.canvas, 0, 350, this.maxPixelNo, 350, 15)
                var step = this.timeValue
                this.sleeperSet.forEach(sleeper=>{
                    const x = parseInt((sleeper.pixelNo - step)/4)
                    drawTrackSleeper(this.canvas, x, 110, x, 400, 30, '#303030', this.timeValue,sleeper.sleeperNo)
                    if(sleeper.isSwitch && sleeper.isSwitch === '1'){
                        drawTrackCrossing(this.canvas, x)
                    }
                })
                this.preTimeValue = this.timeValue
                this.canvas.renderAll()
            },
            async initData() {
                this.sleeperIdSet = new Set()
                this.sleeperSet = new Set()
                const { data: res } = await querySleeperMiniMaxiPixelNoData(this.queryParams)
                this.minPixelNo = parseInt(res[0].pixelNo)
                this.maxPixelNo = parseInt(res[1].pixelNo) - this.minPixelNo - this.canvasWidth > 0 ? parseInt(parseInt(res[1].pixelNo) - this.canvasWidth) : parseInt(res[1].pixelNo)
                this.currentMaxPixelNo = this.minPixelNo
                this.minTimeValue = parseInt(res[0].pixelNo)
                this.timeValue = this.minTimeValue
                this.maxTimeValue = parseInt(res[1].pixelNo) - this.minPixelNo - this.canvasWidth > 0 ? parseInt(parseInt(res[1].pixelNo) - this.canvasWidth) : parseInt(res[1].pixelNo)
                this.clearAll()
                this.draw()
                drawTrack(this.canvas, 0, 150, this.maxPixelNo, 150, 15)
                drawTrack(this.canvas, 0, 350, this.maxPixelNo, 350, 15)
                this.preTimeValue = 0
            },
            async draw() {
                this.queryParams.pixelNo = this.currentMaxPixelNo
                const { data: data } = await querySleeperlist(this.queryParams)
                if(data){
                    this.currentMaxPixelNo = parseInt(data[data.length - 1 ].pixelNo)
                    data.forEach(sleeper=>{
                        if(!this.sleeperIdSet.has(sleeper.id)){
                            this.sleeperIdSet.add(sleeper.id)
                            this.sleeperSet.add(sleeper)
                        }
                    })
                }
                this.renderSleeper()
                this.canvas.renderAll()
            },
            async search() {
                this.pauseAnimation()
                this.timeValue = parseInt(this.keyword)
                this.queryParams.pixelNo = this.keyword
                const { data: data } = await querySleeperlist(this.queryParams)
                if(data){
                    this.currentMaxPixelNo = parseInt(data[data.length - 1 ].pixelNo)
                    data.forEach(sleeper=>{
                        if(!this.sleeperIdSet.has(sleeper.id)){
                            this.sleeperIdSet.add(sleeper.id)
                            this.sleeperSet.add(sleeper)
                        }
                    })
                }
                this.renderSleeper()
            },
            async changeTimeValue(){
               this.queryParams.pixelNo =  this.timeValue
                const { data: data } = await querySleeperlist(this.queryParams)
                if(data){
                    this.currentMaxPixelNo = parseInt(data[data.length - 1 ].pixelNo)
                    data.forEach(sleeper=>{
                        if(!this.sleeperIdSet.has(sleeper.id)){
                            this.sleeperIdSet.add(sleeper.id)
                            this.sleeperSet.add(sleeper)
                        }
                    })
                }
                this.renderSleeper()
            },
            startAnimation() {
                if (!this.isAnimating) {
                    this.isAnimating = true
                    this.animateFrame()
                }
            },
            // 暂停
            pauseAnimation() {
                if (this.isAnimating) {
                    clearInterval(this.animationId)
                    this.isAnimating = false
                }
            },
            // 倍速
            onPlaybackSpeedChange(speed) {
                this.playbackSpeed = speed
                // 如果正在播放，调整动画速度后可能需要重新计算或调整动画状态
                if (this.isAnimating) {
                    this.pauseAnimation() // 先暂停
                    setTimeout(() => {
                        this.startAnimation() // 再按照新的速度开始
                    }, 0)
                }
            },
            // 动画
            animateFrame() {
                this.timeValue += this.playbackSpeed // 使用当前倍速更新时间值
                if (this.timeValue >= this.maxTimeValue) { // 假设100为最大值
                    this.pauseAnimation() // 先暂停
                    this.resetFrame()
                    return;
                }
                if(this.timeValue+ this.canvasWidth + 10>= this.currentMaxPixelNo){
                    this.draw()
                }else{
                    this.renderSleeper()
                }
                this.animationId = setTimeout(() => {
                    this.animateFrame()
                }, 1000 / Math.max(1, 60 / this.playbackSpeed)) // 确保至少每秒一帧，且不超过60fps
            },
            resetFrame(){
                this.timeValue = this.minTimeValue
                this.renderSleeper()
            },
            // 处理页面大小变化
            handleResize() {
                 this.canvasWidth = this.$refs.canvas.parentElement.clientWidth;
                 this.canvas.setWidth(this.canvasWidth)
                this.canvas.renderAll(); // 不管是首次还是后续调整，都需要重新渲染canvas
            },
        },
        created() {
        },
        mounted() {
            this.initCanvas()
            this.initData()
            this.handleResize()
            window.addEventListener('resize', this.handleResize);
        },
        destroyed() {
            window.removeEventListener('resize', this.handleResize);
        },
    }
</script>

<style scoped>
  .canvas-box{
    width: calc(100% - 40px);
    height: 55%;
    border: #999999 1px solid;
    border-radius: 8px;
  }
  .canvas{
    width: 100%;
    height: 100%;
  }
  .timeline-box {
    padding: 20px 0;
    width: calc(100% - 40px);
  }
  /* ...原有样式... */
  .controls {
    display: flex;
    justify-content: center;
    margin-bottom: 20px;
  }
  .mark-box{
   font-size: 18px;
    font-weight: bold;
  }
</style>
